<template>
	<div class="page-wrap">
		<el-form label-width="80px" inline>
			<el-form-item label="学生名字:">
				<el-input
					placeholder="请输入搜索内容"
					prefix-icon="el-icon-search"
					v-model.trim="search.stu_name"
					@input.native="delayGetStudent"
				></el-input>
			</el-form-item>

			<el-form-item label="所在班级:">
				<el-select v-model="search.stu_cls_id" @change="getStudent(true)">
					<el-option label="- 全部 -" :value="0"> </el-option>

					<el-option label="没有班级" :value="null"> </el-option>

					<el-option
						v-for="(item, index) in classList"
						:key="index"
						:label="item.cls_name"
						:value="item.cls_id"
					>
					</el-option>
				</el-select>
			</el-form-item>

			<el-form-item label="学生学历:">
				<el-select
					v-model="search.stu_qualification"
					@change="getStudent(true)"
				>
					<el-option label="- 全部 -" :value="0"> </el-option>

					<el-option
						v-for="(item, index) in dictionary.filter(
							(item) => item.dic_group_key === 'qualification'
						)"
						:key="index"
						:label="item.dic_name"
						:value="item.dic_id"
					>
					</el-option>
				</el-select>
			</el-form-item>

			<el-form-item class="btn-wrap">
				<el-button type="primary" icon="el-icon-plus" @click.native="beforeAdd"
					>新增</el-button
				>

				<el-button
					type="success"
					icon="el-icon-share"
					@click.native="selectAllClass"
					>批量分班</el-button
				>

				<el-button
					type="danger"
					@click.native="exportExcel"
					icon="el-icon-download"
					>导出学生信息</el-button
				>
			</el-form-item>
		</el-form>

		<!-- 表格展示 -->

		<el-table
			:data="studentList"
			style="width: 100%"
			border
			stripe
			highlight-current-row
			@selection-change="handleSelectionChange"
			id="out-table"
		>
			>

			<el-table-column fixed label="#" width="50" align="center" type="index">
			</el-table-column>

			<el-table-column
				fixed
				label="#"
				width="50"
				align="center"
				type="selection"
			>
			</el-table-column>

			<el-table-column fixed label=" 学生名称" align="center" width="120">
				<template slot-scope="{ row }">
					<span>
						{{ row.stu_name }}
					</span>
				</template>
			</el-table-column>
			<el-table-column label="班级" align="center" width="120">
				<template slot-scope="{ row }">
					<span v-if="!row.stu_cls_id" style="color:#ccc">
						无班级
					</span>

					<span v-else>
						{{
							classList.length
								? classList.find((item) => item.cls_id === row.stu_cls_id)
										.cls_name
								: ""
						}}
					</span>
				</template>
			</el-table-column>
			<el-table-column label="存档照片" align="center" width="120">
				<template slot-scope="{ row }">
					<el-popover placement="right" trigger="hover">
						<el-card :body-style="{ padding: '0px' }">
							<img
								:src="
									`${row.stu_avatar ? row.stu_avatar : editorPhoto.noPicture}`
								"
								class="image"
								style="width : 150px; height : 160px;"
							/>
							<div style="padding: 14px;">
								<span>{{ row.stu_name }}</span>
								<span style="color:red;" v-show="!row.stu_avatar"
									>（暂无照片）</span
								>
							</div>
						</el-card>
						<span slot="reference" style="cursor :pointer;color :#409EFF; "
							>预览</span
						>
					</el-popover>
				</template>
			</el-table-column>
			<el-table-column label="性别" align="center" width="120">
				<template slot-scope="{ row }">
					<span>
						{{ row.stu_sex ? "男" : "女" }}
					</span>
				</template>
			</el-table-column>
			<el-table-column label="联系电话" align="center" width="120">
				<template slot-scope="{ row }">
					<span>
						{{ row.stu_phone }}
					</span>
				</template>
			</el-table-column>
			<el-table-column label="联系电话(备用)" align="center" width="120">
				<template slot-scope="{ row }">
					<span>
						{{ row.stu_phone2 }}
					</span>
				</template>
			</el-table-column>
			<el-table-column label="出生日期" align="center" width="120">
				<template slot-scope="{ row }">
					<span>
						{{ row.stu_born }}
					</span>
				</template>
			</el-table-column>
			<el-table-column label="学历" align="center" width="120">
				<template slot-scope="{ row }">
					<span>
						{{
							dictionary.length
								? dictionary.find(
										(item) => item.dic_id === row.stu_qualification
								  ).dic_name
								: ""
						}}
					</span>
				</template>
			</el-table-column>
			<el-table-column label="毕业院校" align="center" width="120">
				<template slot-scope="{ row }">
					<span>
						{{ row.stu_school }}
					</span>
				</template>
			</el-table-column>
			<el-table-column fixed="right" label="操作" align="center" width="500">
				<template slot-scope="scope">
					<el-button
						type="success"
						icon="el-icon-share"
						@click="selectClass(scope.$index, scope.row)"
					>
						分班</el-button
					>

					<el-button
						icon="el-icon-picture"
						type="danger"
						@click="savePhoto(scope.$index, scope.row)"
						>照片存档</el-button
					>

					<el-button
						type="primary"
						icon="el-icon-edit"
						@click="beforeUpdate(scope.$index, scope.row)"
						>编辑</el-button
					>

					<el-button
						type="warning"
						icon="el-icon-delete"
						@click="beforeDelete(scope.$index, scope.row)"
						>删除</el-button
					>
				</template>
			</el-table-column>
		</el-table>

		<!-- 分页 -->
		<el-pagination
			background
			layout="prev, pager, next,jumper,->,sizes,total"
			:total="pagination.total"
			:page-sizes="[5, 8, 10, 12, 15]"
			:page-size.sync="pagination.pageSize"
			:current-page.sync="pagination.currentPage"
			@current-change="getStudent(false)"
			@size-change="getStudent(true)"
		>
		</el-pagination>
		<!-- 新增一个学生 -->
		<el-dialog :visible.sync="editor.isEditor" width="50%" :modal="false">
			<p slot="title" class="title" :class="{ active: editor.isMode }">
				学生维护-{{ editor.isMode ? "新增" : "修改" }}
			</p>

			<el-form
				ref="ruleForm"
				label-width="120px"
				class="demo-ruleForm"
				status-icon
				:model="editor.mode"
				:rules="editor.rules"
			>
				<el-form-item label="学生姓名:" prop="stu_name">
					<el-input
						v-model="editor.mode.stu_name"
						placeholder="请输入学生的名字"
					></el-input>
				</el-form-item>
				<el-form-item label="性别">
					<el-radio-group v-model="editor.mode.stu_sex">
						<el-radio :label="1">男</el-radio>
						<el-radio :label="0">女</el-radio>
					</el-radio-group>
				</el-form-item>
				<el-form-item label="联系电话:" prop="stu_phone">
					<el-input
						type="text"
						placeholder="请输入手机号"
						v-model.trim="editor.mode.stu_phone"
						maxlength="11"
						show-word-limit
					>
					</el-input>
				</el-form-item>
				<el-form-item label="备用电话:" prop="stu_phone2">
					<el-row>
						<el-col :span="16"
							><div class="grid-content">
								<el-input
									v-model="editor.mode.stu_phone2"
									placeholder="请输入备用联系电话(手机号/座机号)"
								></el-input></div
						></el-col>
						<el-col :span="8"
							><div class="grid-content bg-purple">
								例如：028-88888888
							</div></el-col
						>
					</el-row>
				</el-form-item>
				<el-form-item label="出生日期:" prop="stu_born">
					<el-date-picker
						type="date"
						placeholder="请选择选择日期"
						v-model="editor.mode.stu_born"
						style="width: 50%;"
					></el-date-picker>
				</el-form-item>
				<el-form-item label="学历:" prop="stu_qualification">
					<el-select
						v-model="editor.mode.stu_qualification"
						placeholder="- 请选择学生的学历 -"
					>
						<el-option
							v-for="(item, index) in dictionary.filter(
								(dic) => dic.dic_group_key === 'qualification'
							)"
							:key="index"
							:label="item.dic_name"
							:value="item.dic_id"
						></el-option>
					</el-select>
				</el-form-item>
				<el-form-item label="在读/毕业院校:">
					<el-input
						v-model="editor.mode.stu_school"
						placeholder="请输入在读/毕业院校(选填)"
					></el-input>
				</el-form-item>
				<el-form-item label="在校学习专业:">
					<el-input
						v-model="editor.mode.stu_major"
						placeholder="请输入在校学习专业(选填)"
					></el-input>
				</el-form-item>
				<el-form-item label="家庭住址:" prop="stu_address">
					<el-input
						v-model="editor.mode.stu_address"
						placeholder="请输入家庭住址"
					></el-input>
				</el-form-item>
				<el-form-item label="学生备注:">
					<el-input
						type="textarea"
						:rows="4"
						placeholder="请输入学生备注..."
						v-model="editor.mode.stu_remark"
					></el-input>
				</el-form-item>
			</el-form>
			<div slot="footer">
				<el-button type="primary" @click="saveInfo">保存</el-button>
				<el-button @click="editor.isEditor = false">取消</el-button>
			</div>
		</el-dialog>

		<!-- 分班 -->
		<el-dialog
			:visible.sync="editorBegin.isEditorBegin"
			width="40%"
			:modal="false"
		>
			<p slot="title" class="title active">
				分班
			</p>
			<el-form label-width="100px">
				<el-form-item label="班级">
					<el-select v-model="editorBegin.mode.stu_cls_id" placeholder="请选择">
						<el-option label="- 无班级 -" :value="null"> </el-option>
						<el-option
							v-for="(item, index) in classList"
							:key="index"
							:label="item.cls_name"
							:value="item.cls_id"
							:disabled="
								editorBegin.mode.stu_id
									? classList.find(
											(cls) =>
												cls.cls_id ===
												studentList.find(
													(stu) => stu.stu_id === editorBegin.mode.stu_id
												).stu_cls_id
									  )
										? item.cls_dic_id_major !==
												classList.find(
													(cls) =>
														cls.cls_id ===
														studentList.find(
															(stu) => stu.stu_id === editorBegin.mode.stu_id
														).stu_cls_id
												).cls_dic_id_major ||
										  (!!item.cls_begin && !!item.cls_end)
										: !!item.cls_begin && !!item.cls_end
									: !!item.cls_begin && !!item.cls_end
							"
						></el-option>
					</el-select>
				</el-form-item>
			</el-form>
			<div slot="footer">
				<el-button type="primary" @click="okSelectClass">确定</el-button>
				<el-button @click.native="editorBegin.isEditorBegin = false"
					>取消</el-button
				>
			</div>
		</el-dialog>
		<!-- 照片存档 -->
		<el-dialog
			:visible="editorPhoto.isEditorPhoto"
			:modal="false"
			width="50%"
			class="photoDialog"
		>
			<p class="title" slot="title">
				<span>
					照片存档
				</span>
			</p>
			<el-form inline>
				<el-form-item>
					<el-image
						v-if="editorPhoto.mode.stu_avatar_old"
						style="width: 130px; height: 179px"
						:src="editorPhoto.mode.stu_avatar_old"
						fit="fit"
					></el-image>
					<el-image
						v-else
						style="width: 130px; height: 179px"
						:src="editorPhoto.noPicture"
						fit="fit"
					></el-image>
				</el-form-item>

				<el-form-item>
					<el-upload
						ref="photoUpload"
						action="/student/avatarupload"
						name="avatar"
						list-type="picture-card"
						:headers="editorPhoto.uploadHeaders"
						:before-upload="beforeUploadHandler"
						accept=".png,.jpg"
						:on-success="uploadSuccessHandler"
					>
						<i slot="default" class="el-icon-plus"></i>
						<div class="el-upload__tip" slot="tip">
							*只能上传jpg/png文件，且不超过500kb
						</div>
					</el-upload>
				</el-form-item>
			</el-form>
			<div slot="footer" class="dialog-footer">
				<el-button
					:disabled="!editorPhoto.mode.stu_avatar_new"
					@click.native="btnSavePhoto"
					type="primary"
					>确 定</el-button
				>
				<el-button
					@click.native="
						editorPhoto.isEditorPhoto = false;
						$refs.photoUpload.clearFiles();
					"
					>取 消</el-button
				>
			</div>
		</el-dialog>
	</div>
</template>

<script>
import noPicture from "@/views/Student/img/noPicture.png";
import FileSaver from "file-saver";
import XLSX from "xlsx";
export default {
	name: "Student",
	data() {
		return {
			search: {
				stu_name: "",
				stu_cls_id: 0, //0代表全部 null代表没有的班级
				stu_qualification: 0, //0代表全部
			},
			pagination: {
				total: 0,
				pageSize: 5,
				currentPage: 1,
			},
			editorPhoto: {
				isEditorPhoto: false,
				noPicture: noPicture,
				mode: {
					stu_id: null,
					stu_avatar_old: null,
					stu_avatar_new: null,
				},
				uploadHeaders: {
					Authorization: this.$cookies.get("token"),
				},
			},
			editorBegin: {
				isEditorBegin: false,
				isAll: false,
				mode: {
					stu_id: null,
					stu_ids: [],
					stu_cls_id: null,
				},
			},
			editor: {
				isEditor: false,
				isMode: true,
				mode: {
					stu_name: "",
					stu_avatar: null,
					stu_cls_id: null,
					stu_sex: 1,
					stu_phone: "",
					stu_phone2: "",
					stu_born: "",
					stu_qualification: null,
					stu_school: "",
					stu_major: "",
					stu_address: "",
					stu_remark: "",
				},
				rules: {
					stu_name: [
						{
							required: true,
							message: "请输入姓名",
							trigger: "blur",
						},
					],
					stu_phone: [
						{
							validator(rule, value, callback) {
								if (value === "") callback(new Error("手机号不能为空"));
								else if (
									!/^0?(13[0-9]|15[012356789]|17[013678]|18[0-9]|14[57])[0-9]{8}$/.test(
										value
									)
								)
									callback(new Error("手机格式不正确"));
								else callback();
							},
							trigger: "change",
						},
					],
					stu_phone2: [
						{
							required: true,
							message: "请输入备用电话",
							trigger: "blur",
						},
					],
					stu_born: [
						{
							required: true,
							message: "请填写出生日期",
							trigger: "blur",
						},
					],
					stu_qualification: [
						{
							required: true,
							message: "请选择学历",
							trigger: "blur",
						},
					],
					stu_address: [
						{
							required: true,
							message: "请填写家庭地址",
							trigger: "blur",
						},
					],
				},
			},
			studentList: [],
			dictionary: [],
			classList: [],
			timerStudent: null, //防抖
		};
	},
	methods: {
		//定义导出Excel表格事件
		exportExcel() {
			/* 从表生成工作簿对象 */
			var wb = XLSX.utils.table_to_book(document.querySelector("#out-table"));
			/* 获取二进制字符串作为输出 */
			var wbout = XLSX.write(wb, {
				bookType: "xlsx",
				bookSST: true,
				type: "array",
			});
			try {
				FileSaver.saveAs(
					//Blob 对象表示一个不可变、原始数据的类文件对象。
					//Blob 表示的不一定是JavaScript原生格式的数据。
					//File 接口基于Blob，继承了 blob 的功能并将其扩展使其支持用户系统上的文件。
					//返回一个新创建的 Blob 对象，其内容由参数中给定的数组串联组成。
					new Blob([wbout], { type: "application/octet-stream" }),
					//设置导出文件名称
					"sheetjs.xlsx"
				);
			} catch (e) {
				if (typeof console !== "undefined") console.log(e, wbout);
			}
			return wbout;
		},
		// 照片存档
		savePhoto(index, row) {
			this.editorPhoto.isEditorPhoto = true;
			this.editorPhoto.mode.stu_id = row.stu_id;
			this.editorPhoto.mode.stu_avatar_old = row.stu_avatar;
			this.editorPhoto.mode.stu_avatar_new = null;
		},
		// 保存存档照片
		btnSavePhoto() {
			this.$confirm("确定替换当前照片吗?", "提示", {
				confirmButtonText: "确定",
				cancelButtonText: "取消",
				type: "warning",
			})
				.then(() => {
					this.$http({
						url: "/student/avatarupdate",
						method: "post",
						data: {
							...this.editorPhoto.mode,
						},
					}).then((res) => {
						console.log(res);
						this.studentList.find(
							(item) => item.stu_id === this.editorPhoto.mode.stu_id
						).stu_avatar = res;
						this.editorPhoto.isEditorPhoto = false;
						// 清除临时显示的图片
						this.$refs.photoUpload.clearFiles();
						this.$message({
							type: "success",
							message: "替换成功!",
						});
					});
				})
				.catch(() => {
					this.$message({
						type: "info",
						message: "已取消",
					});
				});
		}, //上传图片成功的处理时间
		uploadSuccessHandler(response, file, fileList) {
			console.log(response);
			if (response.status === 200) {
				this.editorPhoto.mode.stu_avatar_new = response.data;
				if (fileList.length > 1) {
					fileList.shift();
				}
			} else {
				this.$message.error(response.message);
			}
		},
		// 在此函数内部对要上传的资源进行类型、大小等等验证
		beforeUploadHandler(file) {
			const isJPG = file.type === "image/jpg";
			const isPNG = file.type === "image/png";
			const isJPEG = file.type === "image/jpeg";
			const isLt2M = file.size / 1024 / 1024 < 2;

			if (!isJPG && !isPNG && !isJPEG) {
				this.$message.error("上传头像图片只能是 JPG 格式!");
			}
			if (!isLt2M) {
				this.$message.error("上传头像图片大小不能超过 2MB!");
			}
			return isJPG || isPNG || (isJPEG && isLt2M);
		},
		handleSelectionChange(selectAll) {
			this.editorBegin.mode.stu_ids = [];
			console.log("多选:", selectAll);
			selectAll.forEach((element) => {
				this.editorBegin.mode.stu_ids.push(element.stu_id);
			});
		},
		selectAllClass() {
			if (!this.editorBegin.mode.stu_ids.length) {
				this.$message({
					message: "请勾选要分班的学生~",
					type: "warning",
				});
				return;
			}
			// 批量分班
			this.$confirm("确定要分班吗?", "提示", {
				confirmButtonText: "确定",
				cancelButtonText: "取消",
				type: "warning",
			})
				.then(() => {
					// 批量分班标识
					this.editorBegin.isAll = true;
					this.editorBegin.isEditorBegin = true;
					this.editorBegin.mode.stu_id = null;
					// this.editorBegin.mode.stu_ids = [];
					this.editorBegin.mode.stu_cls_id = null;
				})
				.catch(() => {
					this.$message({
						type: "info",
						message: "已取消",
					});
				});
		},
		selectClass(index, row) {
			// 单个分班

			this.$confirm("确定要分班吗?", "提示", {
				confirmButtonText: "确定",
				cancelButtonText: "取消",
				type: "warning",
			})
				.then(() => {
					this.editorBegin.isAll = false;
					this.editorBegin.isEditorBegin = true;

					this.editorBegin.mode.stu_id = row.stu_id;
					this.editorBegin.mode.stu_ids = [];
					this.editorBegin.mode.stu_cls_id = row.stu_cls_id;
				})
				.catch(() => {
					this.$message({
						type: "info",
						message: "已取消",
					});
				});
		},
		okSelectClass() {
			// 选择班级
			this.$http({
				url: "/student/assignclass",
				method: "post",
				data: {
					...this.editorBegin.mode,
				},
			}).then((res) => {
				if (this.editorBegin.isAll) {
					this.editorBegin.mode.stu_ids.forEach((item) => {
						this.studentList.find(
							(stu) => stu.stu_id === item
						).stu_cls_id = this.editorBegin.mode.stu_cls_id;
					});
				} else {
					this.studentList.find(
						(item) => item.stu_id === this.editorBegin.mode.stu_id
					).stu_cls_id = this.editorBegin.mode.stu_cls_id;
				}

				//分班成功
				this.$message({
					type: "success",
					message: "分班成功",
				});
				this.editorBegin.isEditorBegin = false;
			});
		},
		beforeDelete(index, row) {
			this.$confirm("此操作将永久删除该记录, 是否继续?", "提示", {
				confirmButtonText: "确定",
				cancelButtonText: "取消",
				type: "warning",
			})
				.then(() => {
					// 删除一个学生
					this.$http({
						url: `/student/remove/${row.stu_id}`,
						method: "post",
					}).then((res) => {
						//删除成功
						this.studentList.splice(
							this.studentList.findIndex((item) => item.stu_id === row.stu_id),
							1
						);
						this.$message({
							type: "success",
							message: "删除成功",
						});
					});
				})
				.catch(() => {
					this.$message({
						type: "info",
						message: "已取消删除",
					});
				});
		},
		initFrom() {
			if (this.$refs.ruleForm) this.$refs.ruleForm.resetFields();
		},
		saveInfo() {
			// 保存
			this.$refs.ruleForm
				.validate()
				.then(() => {
					//验证通过
					if (this.editor.isMode) {
						//新增
						this.$http({
							url: "/student/add",
							method: "post",
							data: {
								...this.editor.mode,
							},
						}).then((res) => {
							console.log("新增成功:", res);
							this.editor.mode.stu_id = res;
							this.studentList.push({ ...this.editor.mode });
							this.$message({
								type: "success",
								message: "新增成功",
							});
						});
					} else {
						// 编辑
						this.$http({
							url: "/student/update",
							method: "post",
							data: {
								...this.editor.mode,
							},
						}).then((res) => {
							console.log("更新成功:", res);
							this.studentList.splice(
								this.studentList.findIndex(
									(item) => item.stu_id === this.editor.mode.stu_id
								),
								1,
								{ ...this.editor.mode }
							);
							this.$message({
								type: "success",
								message: "修改成功",
							});
						});
					}
					this.editor.isEditor = false;
				})
				.catch(() => {
					//验证失败
				});
		},
		delayGetStudent() {
			// 防抖请求
			if (this.timerStudent) clearTimeout(this.timerStudent);
			setTimeout(() => {
				this.getStudent(true);
			}, 800);
		},
		beforeAdd() {
			this.initFrom();
			// 开始新增
			this.editor.isEditor = true;
			this.editor.isMode = true;

			this.editor.mode.stu_name = "";
			this.editor.mode.stu_avatar = null;
			this.editor.mode.stu_cls_id = null;
			this.editor.mode.stu_sex = 1;
			this.editor.mode.stu_phone = "";
			this.editor.mode.stu_phone2 = "";
			this.editor.mode.stu_born = "";
			this.editor.mode.stu_qualification = null;
			this.editor.mode.stu_school = "";
			this.editor.mode.stu_major = "";
			this.editor.mode.stu_address = "";
			this.editor.mode.stu_remark = "";
		},
		beforeUpdate(index, row) {
			this.initFrom();
			this.editor.isEditor = true;
			this.editor.isMode = false;
			this.editor.mode = { ...row };
		},
		// 分页查询学生信息
		getStudent(isInit = true) {
			if (isInit) this.pagination.currentPage = 1;
			this.$http({
				url: "/student/list",
				method: "post",
				data: {
					...this.search,
					begin: (this.pagination.currentPage - 1) * this.pagination.pageSize,
					pageSize: this.pagination.pageSize,
				},
			}).then((res) => {
				console.log("分页学生信息:", res);
				let { total, list } = res;
				this.studentList = list;
				this.pagination.total = total;
			});
		},
		getDictionary() {
			this.$http({
				url: "/dictionary/all",
				method: "get",
			}).then((res) => {
				console.log("所有字典数据:", res);
				this.dictionary = res;
			});
		},
		// 所有班级信息
		getClass() {
			this.$http({
				url: "/class/all",
				method: "get",
			}).then((res) => {
				console.log("所有班级信息:", res);
				this.classList = res;
			});
		},
	},
	created() {
		this.getStudent(true);
		this.getDictionary();
		this.getClass();
	},
};
</script>

<style lang="stylus" scoped>

.page-wrap
    position absolute
    top 0
    left 0
    right 0
    bottom 0
    display flex
    flex-direction column
    .el-form
        flex-shrink 0
        .el-form-item
            &.btn-wrap
                float right
    .el-table
        flex-grow 1
    .el-pagination
        flex-shrink 0
    .el-dialog
        .title
            padding 10px 30px
            font-size 18px
            color white
            background-color #F56C6C
            &.active
                background-color #67C23A
        .bg-purple
            background-color #eee
            text-align center
            color #bbb
    .photoDialog
        .el-form
            display flex
            justify-content space-around
            align-items flex-start
            .el-upload__tip
                color red
                font-size 14px
            .el-form-item
                & >>> .el-upload-list--picture-card .el-upload-list__item, & >>> .el-upload.el-upload--picture-card
                    width :130px
                    height : 179px
                & >>> .el-upload
                    position relative
                    .el-icon-plus
                        position absolute
                        top 50%
                        left 50%
                        transform translate(-50%,-50%)
</style>
